function strtable = Mat2TexC(data,format,row_labels, col_labels, ErrsOrPvals, Options, Caption)

% complete table with \begin and \end line

% strtable = Mat2Tex(data,format,row_labels, col_labels, ErrsOrPvals, Options)
%
% tranforms the matrix(data) into LaTeX 'tabular' environment compatible  text
% INPUT   -- data - Matlab matrix with values,
%  			-- format: C-format string.
% 			-- row_labels, col_labels --- self_explanatory (optional - default value is {})
%         -- stderrs - either stderrs or pvalues (optional)
%         -- Options Structure (optional)
%  Options
%
% the result is the string array containing the table in LaTeX notation
% no additonal transformation for Latex is needed
%
% EXAMPLES OF USE:
%  rows = {'r1','r2','r3'}; cols = {'c1','c2'}; data=[1 2; 3 4; 5 6];
%  Opts.Style = 'jf'; Opts.digit='c';
%  Mat2Tex(data,'%5.3f',rows,cols, [], Opts)
%
%   Alexei Jiltsov <ajiltsov@lbs.ac.uk>, 20 September 1998
%   Requires MATLAB version 5
% modification of June, 2, 1999 allows stderrs (or t-stats) to
% be printed just below the regression results
% it is also modified to skip NaN symbols which
% makes it convinient to present regression results
% on different parameter sets
% modificaiton on 6  November 1999   -- implement JF style table by introducing Option
% modification on 18 September 1999  -- empty row_label are  possible

%   Modified by Ilya Strebulaev <istrebulaev@stanford.edu>, 24 September 2004
% number of digits can vary across rows or columns
% For this Mat2Tex(data,digit,rows,cols, [], Opts) is used when digit is
% rowsX1 and the  Opts.digit='r' or columnsX1 and then Opts.digit='c';

[rc, cc] = size(data);

% ====

do_errs = 0;

if (nargin < 6),  Options     = []; end;
if (nargin < 5),  ErrsOrPvals = []; end;
if (nargin < 4),  col_labels  = []; end;
if (nargin < 3),  row_labels  = []; end;

eval(mat2texfillDefaultOptions(Options));

if (~isempty(ErrsOrPvals)),
    if (any(size(ErrsOrPvals) ~= [rc, cc])),
        error('mat2tex:wrong size of Errs or Pvals');
    end;
else
    do_errs = 0; do_pvals = 0;
end;

if (iscell(format)), format = reshape(format,length(format),1); end;
a=format;

kk=0;
if (isempty(a)),
    format = cell(rc,cc);
    [format{:}] = deal('%5.2f');
    kk=1;
elseif Options.digit=='c' & size(a,1) == cc & size(a,1) > 1, %columns
    format = repmat(a',rc,1);
    kk=1;
elseif Options.digit=='r' & size(a,1) == rc & size(a,1) > 1, %rows
    format = repmat(a,1,cc);
    kk=1;
elseif (size(a,1) == 1),
    tmp = format;
    format = cell(rc,cc);
    [format{:}] = deal(tmp);
    kk=1;
elseif kk==0,
    error('Mat2Tex: format is not of appropriate size');
end;

rowempt = 0;
row_labels = reshape(row_labels,length(row_labels),1);
col_labels = reshape(col_labels,length(col_labels),1);

if (isempty(row_labels))
    s = '{';  rowempt =1;
elseif (size(row_labels,1)~=rc),
    error('Mat2Tex: number of row labels is not apppropriate');
else
    s = sprintf('{%sl',ColsSep);
end;

% === create the alignment mode for the column (all centered as a default)

for i=1:cc,
    s = [s,sprintf('%s%s',ColsSep, ColsAlign)];
end;
s = [s,sprintf('%s}',ColsSep)];

strtable = ['\begin{table}'];
strtable = strvcat(strtable,['\caption{',Caption,'}']);
strtable = strvcat(strtable,'\begin{center}');
strtable = strvcat(strtable,['\begin{tabular}',s]);
strtable = strvcat(strtable,'\hline');


if (~isempty(col_labels))
    if size(col_labels,1)==cc
        s = '';
        if rowempt==1
            s = col_labels{1};
            for i=2:cc
                s = [s ' & ' col_labels{i}];
            end
        else
            for i=1:cc
                s = [s ' & ' col_labels{i}];
            end
            
        end
        s = [s,' \\'];
        s = strvcat(s,'\hline');
        strtable = strvcat(strtable,s);
    end
    if size(col_labels,1)==cc+1
        s = '';
        for i=1:cc
            s = [s col_labels{i} ' & '];
        end
        s = [s col_labels{end}];
        s = [s,' \\'];
        s = strvcat(s,'\hline');
        strtable = strvcat(strtable,s);
    end
    if size(col_labels,1)<cc
        error('Mat2Tex: number of column labels is not apppropriate');
    end
end

% ==== MAIN LOOP === filling the matrix by moving down row-by-row

for i =1:rc,                        % ----- row loop
    s = ''; see = '';
    naninerr = 0;
    for j=1:cc,
        ss = sprintf(format{i,j}, data(i,j));
        if (isnan(data(i,j))), ss = ''; end;
        s	 = [s, ss, ' & '];
        if (do_errs),
            se  = sprintf(['(',format{i,j},')'], ErrsOrPvals(i,j));
            if (isnan(ErrsOrPvals(i,j))), se = '';  naninerr = naninerr + 1; end;
            see = [see, se,' & '];
        end;
        if (do_pvals),
            if (ErrsOrPvals(i,j) > PvalsCrit)
                se  = sprintf([PvalsFormat], 100*ErrsOrPvals(i,j));
            else
                se  = sprintf(['<','%d\\%%'], 100*PvalsCrit);
            end;
            if (isnan(ErrsOrPvals(i,j))), se = '';  naninerr = naninerr + 1; end;
            see = [see, se,' & '];
        end;
    end;
    sz   = size(s,2);   s    = s(1:sz-3);    s    = [s,' \\'];
    
    if (do_errs | do_pvals),
        sz   = size(see,2);   see  = see(1:sz-3);    see  = [see,' \\'];
    end;
    
    if (~rowempt),
        s		= [row_labels{i},' & ',s];
        if (do_errs | do_pvals ), see	= [' & ',see]; end;
    end;
    if ((do_errs | do_pvals) & naninerr < cc), % if == cc then the row consisit of nans and should be skiped
        s = strvcat(s, see, RowsSep);
    else
        s = strvcat(s,RowsSep);
    end;
    strtable = strvcat(strtable,s);
end;
if ~strcmp(RowsSep,'\hline'),
    strtable = strvcat(strtable,'\hline');
end;

strtable = strvcat(strtable,'\end{tabular}');
strtable = strvcat(strtable,'\end{center}');
strtable = strvcat(strtable,'\end{table}');

% ================== OPTIONS FUNCTION =====================================================================


function [defExecLine] = mat2texfillDefaultOptions(OptIn)
%
% Purpose: returns default options for the main porgram
% if the user specifies the option by assigning the corresponding
% field then the function does not change it, but if the field of
% the options structure is missing or
%
%   Options:
%       --- Style     -- predefined style -- ALL other values are ignored and filled
%                     -- accordingly to the style chosen
%       --- RowSep    -- how to separate rows, the default is '\hline' -- can be empty or something like \smallskip
%       --- ColsSep   -- how to separate cols, the default is '|' -- can be empty
%       --- ColsAlign -- 'l','c', 'r'  -- the default is 'c'
%       --- pvalsCrit --
%

if isfield(OptIn, 'Style'),
    switch OptIn.Style
        case 'jf',  % jf stands for journal of finance
            defExecLine = 'RowsSep = ''''; ColsSep = ''''; ColsAlign = ''c''; ';
            if (isfield(OptIn,'Pvals')),
                defExecLine = [defExecLine, 'do_pvals = 1; do_errs = 0; PvalsCrit = 0.01; PvalsFormat = ''%5.1f\\%%'';    '; ];
            else
                defExecLine = [defExecLine, 'do_errs = 1; do_pvals = 0; '; ];
            end;
        otherwise,
            error('unknown table style');
    end;
end;

if isempty(OptIn),  % this is default ....
    defExecLine = 'RowSep = ''\hline''; ColsSep = ''|''; ColsAlign = ''c''; ';
    defExecLine = [defExecLine, 'do_errs = 1; '; ];
end;
